/**
 * @file
 * Settings window implementation.
 *
 * Kisa provides spell checking as you type and displays the result in a small
 * window on your Desktop.
 *
 * Copyright (c) 2009 by Pete Black <theblackpeter@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * @author Pete Black <theblackpeter@gmail.com>
 */
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QtDebug>

#include "kisasettings.h"
#include "kisalib.h"

/**
 * Instances of this class will have this name.
 * @note this is not a unique identifier, just a common name.
 */
#ifndef OBJECT_NAME
#define OBJECT_NAME "kisasettings"
#endif

/**
 * Name used when outputting debug information.
 */
#ifndef OBJECT_DEBUG_NAME
#define OBJECT_DEBUG_NAME "kisasettings:"
#endif

KisaSettings::KisaSettings(QWidget* parent, Qt::WFlags fl) :
  QDialog(parent, fl), Ui::KisaSettings() {

  setupUi(this);

  // whenever accepting settings
  connect(this, SIGNAL(accepted()), this, SLOT(writeSettings()));

  // add/remove itemes from the ignore list
  connect(addItemButton, SIGNAL(clicked()), this, SLOT(addIgnoreListItem()));
  connect(removeItemButton, SIGNAL(clicked()), this, SLOT(removeIgnoreListItem()));

  // whenever the show flag is toggled
  connect(checkBox_13, SIGNAL(toggled(bool)), this, SLOT(updateDictionariesComboBox()));

  // custom command icon selection
  connect(toolButton, SIGNAL(clicked()), this, SLOT(updateCustomCommandIcon()));

  // get the library instance
  kisaLib = KisaLib::instance();

  // get the installed dictionaries
  // make sure that kisalib has been properly initiated before this call
  updateDictionariesComboBox();

  // set the default font value to that of what was used in the designer
  m_font = fontComboBox->currentFont();
  m_font.setPointSize(spinBox_1->value());
  m_font.setBold(checkBox_7->isChecked());
  m_font.setItalic(checkBox_6->isChecked());

  // set some nice tab icons
  tabWidget->setTabIcon(0, QIcon("icons:configure.png"));

  if(QFile("icons:preferences-desktop-font.png").exists())
    tabWidget->setTabIcon(1, QIcon("icons:preferences-desktop-font.png"));
  else
    tabWidget->setTabIcon(1, QIcon("icons:fonts.png"));

  if(QFile("icons:preferences-system-windows.png").exists())
    tabWidget->setTabIcon(2, QIcon("icons:preferences-system-windows.png"));
  else
    tabWidget->setTabIcon(2, QIcon("icons:list.png"));

  // now the add and remove button icons, if there are no such images use text
  if(QFile("icons:list-add.png").exists())
    addItemButton->setIcon(QIcon("icons:list-add.png"));
  else
    addItemButton->setText("+");

  if(QFile("icons:list-remove.png").exists())
    removeItemButton->setIcon(QIcon("icons:list-remove.png"));
  else
    removeItemButton->setText("-");

  // and the dialog buttons
  if(QFile("icons:ok.png").exists())
    okButton->setIcon(QIcon("icons:ok.png"));
  else
    okButton->setIcon(QIcon("icons:dialog-ok.png"));

  if(QFile("icons:cancel.png").exists())
    cancleButton->setIcon(QIcon("icons:cancel.png"));
  else
    cancleButton->setIcon(QIcon("icons:dialog-cancel.png"));

  m_closedVisible = true;

  qDebug() << OBJECT_DEBUG_NAME << OBJECT_NAME << "created";
}

KisaSettings::~KisaSettings() {
  qDebug() << OBJECT_DEBUG_NAME << OBJECT_NAME << "destroyed";
}

void KisaSettings::addIgnoreListItem() {
  // make sure we don't add any empty rows
  if(lineEdit_1->isModified()) {
    QString item = lineEdit_1->text();

    // don't add our own name
    if(!item.contains("kisa", Qt::CaseInsensitive)) {
      listWidget->addItem(item);

      qDebug() << OBJECT_DEBUG_NAME << "added" << item << "to the ignore list";
    }
  }
}

const QStringList KisaSettings::createIgnoreList() {
  QString ignoreListRegExp = createRegExpString();
  QString ignoreListStr = ignoreListRegExp.remove("(");
  ignoreListStr = ignoreListStr.remove(")");

  return ignoreListStr.split("|");
}

const QString KisaSettings::createRegExpString() {
  // there is no isEmpty()?!
  if(!listWidget->count())
    return "";

  QString regExp = "(";
  for(int i = 0; i < listWidget->count(); i++) {
    if(i == 0)
      regExp += (listWidget->item(i))->text();
    else
      regExp += "|" + (listWidget->item(i))->text();
  }

  regExp += ")";

  return regExp;
}

void KisaSettings::readSettings(QString fileName) {
  // set the default file name if none
  if(fileName.isEmpty()) {
    fileName = QSettings().fileName();
    fileName = fileName.toLower();
  }

  QSettings settings(fileName, QSettings::IniFormat, this);

  qDebug() << OBJECT_DEBUG_NAME << "reading settings from" << fileName;

  settings.beginGroup("State");

  // we don't want to move or resize the main window if its visible already
  if(!parentWidget()->isVisible()) {
    parentWidget()->resize(settings.value("size", QSize(200, 25)).toSize());
    parentWidget()->move(settings.value("position", QPoint(0, 0)).toPoint());
    m_closedVisible = settings.value("visible", true).toBool();
  }

  settings.endGroup();

  settings.beginGroup("Settings");
  checkBox_9->setChecked(settings.value("addToClipboard", true).toBool());

  lineEdit_3->setText(settings.value("customCommand",
                                     lineEdit_3->text()).toString());
  m_iconFileName = settings.value("customCommandIcon",
                                  ":/icons/google.png").toString();
  toolButton->setIcon(QIcon(m_iconFileName));
  lineEdit_2->setText(settings.value("customCommandName",
                                     lineEdit_2->text()).toString());

  QString currentFont = fontComboBox->currentFont().toString();
  m_font.fromString(settings.value("font", currentFont).toString());

  fontComboBox->setCurrentFont(m_font);
  spinBox_1->setValue(m_font.pointSize());
  checkBox_7->setChecked(m_font.bold());
  checkBox_6->setChecked(m_font.italic());

  QStringList defaultIgnoreList = QString("kickoff, kwin, toolbar").split(", ");
  m_ignoreList = settings.value("ignoreList", defaultIgnoreList).toStringList();
  listWidget->clear();
  listWidget->addItems(m_ignoreList);

  checkBox_15->setChecked(settings.value("hyphenAsPunctuation", false).toBool());
  checkBox_12->setChecked(settings.value("keepOnTop", true).toBool());
  checkBox_14->setChecked(settings.value("showButton", true).toBool());
  checkBox_11->setChecked(settings.value("replaceInClient", false).toBool());
  checkBox_13->setChecked(settings.value("showFlag", true).toBool());
  checkBox_5->setChecked(settings.value("showSuggestionsPopup", true).toBool());
  checkBox_8->setChecked(settings.value("showSystrayPopup", false).toBool());
  spinBox_3->setValue(settings.value("suggestionsPopupDuration", 5).toInt());
  spinBox_2->setValue(settings.value("systrayPopupDuration", 5).toInt());
  checkBox_10->setChecked(settings.value("updateOnNewLayout", false).toBool());
  settings.endGroup();
}

void KisaSettings::removeIgnoreListItem() {
  QString item = (listWidget->takeItem(listWidget->currentRow()))->text();

  qDebug() << OBJECT_DEBUG_NAME << "removed" << item << "from the ignore list";
}

void KisaSettings::updateCustomCommandIcon() {
  QString filter = tr("Image Files");
  filter += " (*.bmp *.gif *.jpg *.jpeg *.pbm *.png *.ppm *.xbm *.xpm)";

  // get the icon filename
  m_iconFileName = QFileDialog::getOpenFileName(this, tr("Select Icon"),
                                                QDir::homePath(), filter);

  if(!m_iconFileName.isEmpty())
    toolButton->setIcon(QIcon(m_iconFileName));
}

void KisaSettings::updateDictionariesComboBox() {
  comboBox_2->clear();

  // get the known dictionaries and their 5 character code representation
  QStringList dictionaries = kisaLib->dictionaries();
  QStringList dictionaryCodes = kisaLib->dictionaryCodesGuessed();

  for(int i = 0; i < dictionaries.size(); i++) {
    QString dictionary = dictionaries.at(i);
    QString dictionaryCode = dictionaryCodes.at(i);

    if(showFlag()) {
      // the dictionary code is on the form language_COUNTRY,
      // see kisaLib->dictionaryCodes()
      QString countryCode = dictionaryCode.right(2);
      QString flagURL = kisaLib->getCountryFlagURL(countryCode);

      comboBox_2->addItem(QIcon(flagURL), dictionary, dictionaryCode);
    }
    else
      comboBox_2->addItem(dictionary, dictionaryCode);
  }

  comboBox_2->setCurrentIndex(kisaLib->currentDictionaryIndex());

  qDebug() << OBJECT_DEBUG_NAME << "updated dictionary combo box";
}

void KisaSettings::writeSettings(QString fileName) {
  // set the default file name if none
  if(fileName.isEmpty()) {
    fileName = QSettings().fileName();
    fileName = fileName.toLower();
  }

  m_ignoreList = createIgnoreList();
  m_font = fontComboBox->currentFont();
  m_font.setPointSize(spinBox_1->value());
  m_font.setBold(checkBox_7->isChecked());
  m_font.setItalic(checkBox_6->isChecked());

  QSettings settings(fileName, QSettings::IniFormat, this);

  settings.beginGroup("State");
  settings.setValue("size", parentWidget()->size());
  settings.setValue("position", parentWidget()->pos());
  settings.setValue("visible", parentWidget()->isVisible());
  settings.endGroup();

  settings.beginGroup("Settings");
  settings.setValue("addToClipboard", checkBox_9->isChecked());
  settings.setValue("customCommand", lineEdit_3->text());
  settings.setValue("customCommandIcon", m_iconFileName);
  settings.setValue("customCommandName", lineEdit_2->text());
  settings.setValue("font", m_font.toString());
  settings.setValue("ignoreList", createIgnoreList());
  settings.setValue("hyphenAsPunctuation", checkBox_15->isChecked());
  settings.setValue("keepOnTop", checkBox_12->isChecked());
  settings.setValue("replaceInClient", checkBox_11->isChecked());
  settings.setValue("showButton", checkBox_14->isChecked());
  settings.setValue("showFlag", checkBox_13->isChecked());
  settings.setValue("showSuggestionsPopup", checkBox_5->isChecked());
  settings.setValue("showSystrayPopup", checkBox_8->isChecked());
  settings.setValue("suggestionsPopupDuration", spinBox_3->value());
  settings.setValue("systrayPopupDuration", spinBox_2->value());
  settings.setValue("updateOnNewLayout", checkBox_10->isChecked());
  settings.endGroup();

  qDebug() << OBJECT_DEBUG_NAME << "wrote settings to" << settings.fileName();
}
